﻿package org.flixel
{
    import flash.events.*;
    import flash.media.*;
    import flash.net.*;

    public class FlxSound extends FlxBasic
    {
        public var x:Number;
        public var y:Number;
        public var survive:Boolean;
        public var name:String;
        public var artist:String;
        public var amplitude:Number;
        public var amplitudeLeft:Number;
        public var amplitudeRight:Number;
        public var autoDestroy:Boolean;
        protected var _sound:Sound;
        protected var _channel:SoundChannel;
        protected var _transform:SoundTransform;
        protected var _position:Number;
        protected var _volume:Number;
        protected var _volumeAdjust:Number;
        protected var _looped:Boolean;
        protected var _target:FlxObject;
        protected var _radius:Number;
        protected var _pan:Boolean;
        protected var _fadeOutTimer:Number;
        protected var _fadeOutTotal:Number;
        protected var _pauseOnFadeOut:Boolean;
        protected var _fadeInTimer:Number;
        protected var _fadeInTotal:Number;

        public function FlxSound()
        {
            this.createSound();
            return;
        }// end function

        protected function createSound() : void
        {
            this.destroy();
            this.x = 0;
            this.y = 0;
            if (this._transform == null)
            {
                this._transform = new SoundTransform();
            }
            this._transform.pan = 0;
            this._sound = null;
            this._position = 0;
            this._volume = 1;
            this._volumeAdjust = 1;
            this._looped = false;
            this._target = null;
            this._radius = 0;
            this._pan = false;
            this._fadeOutTimer = 0;
            this._fadeOutTotal = 0;
            this._pauseOnFadeOut = false;
            this._fadeInTimer = 0;
            this._fadeInTotal = 0;
            exists = false;
            active = false;
            visible = false;
            this.name = null;
            this.artist = null;
            this.amplitude = 0;
            this.amplitudeLeft = 0;
            this.amplitudeRight = 0;
            this.autoDestroy = false;
            return;
        }// end function

        override public function destroy() : void
        {
            this.kill();
            this._transform = null;
            this._sound = null;
            this._channel = null;
            this._target = null;
            this.name = null;
            this.artist = null;
            super.destroy();
            return;
        }// end function

        override public function update() : void
        {
            var _loc_3:Number = NaN;
            if (this._position != 0)
            {
                return;
            }
            var _loc_1:Number = 1;
            var _loc_2:Number = 1;
            if (this._target != null)
            {
                _loc_1 = FlxU.getDistance(new FlxPoint(this._target.x, this._target.y), new FlxPoint(this.x, this.y)) / this._radius;
                if (_loc_1 < 0)
                {
                    _loc_1 = 0;
                }
                if (_loc_1 > 1)
                {
                    _loc_1 = 1;
                }
                if (this._pan)
                {
                    _loc_3 = (this._target.x - this.x) / this._radius;
                    if (_loc_3 < -1)
                    {
                        _loc_3 = -1;
                    }
                    else if (_loc_3 > 1)
                    {
                        _loc_3 = 1;
                    }
                    this._transform.pan = _loc_3;
                }
            }
            if (this._fadeOutTimer > 0)
            {
                this._fadeOutTimer = this._fadeOutTimer - FlxG.elapsed;
                if (this._fadeOutTimer <= 0)
                {
                    if (this._pauseOnFadeOut)
                    {
                        this.pause();
                    }
                    else
                    {
                        this.stop();
                    }
                }
                _loc_2 = this._fadeOutTimer / this._fadeOutTotal;
                if (_loc_2 < 0)
                {
                    _loc_2 = 0;
                }
            }
            else if (this._fadeInTimer > 0)
            {
                this._fadeInTimer = this._fadeInTimer - FlxG.elapsed;
                _loc_2 = this._fadeInTimer / this._fadeInTotal;
                if (_loc_2 < 0)
                {
                    _loc_2 = 0;
                }
                _loc_2 = 1 - _loc_2;
            }
            this._volumeAdjust = _loc_1 * _loc_2;
            this.updateTransform();
            if (this._transform.volume > 0 && this._channel != null)
            {
                this.amplitudeLeft = this._channel.leftPeak / this._transform.volume;
                this.amplitudeRight = this._channel.rightPeak / this._transform.volume;
                this.amplitude = (this.amplitudeLeft + this.amplitudeRight) * 0.5;
            }
            return;
        }// end function

        override public function kill() : void
        {
            super.kill();
            if (this._channel != null)
            {
                this.stop();
            }
            return;
        }// end function

        public function loadEmbedded(param1:Class, param2:Boolean = false, param3:Boolean = false) : FlxSound
        {
            this.stop();
            this.createSound();
            this._sound = new param1;
            this._looped = param2;
            this.updateTransform();
            exists = true;
            return this;
        }// end function

        public function loadStream(param1:String, param2:Boolean = false, param3:Boolean = false) : FlxSound
        {
            this.stop();
            this.createSound();
            this._sound = new Sound();
            this._sound.addEventListener(Event.ID3, this.gotID3);
            this._sound.load(new URLRequest(param1));
            this._looped = param2;
            this.updateTransform();
            exists = true;
            return this;
        }// end function

        public function proximity(param1:Number, param2:Number, param3:FlxObject, param4:Number, param5:Boolean = true) : FlxSound
        {
            this.x = param1;
            this.y = param2;
            this._target = param3;
            this._radius = param4;
            this._pan = param5;
            return this;
        }// end function

        public function play(param1:Boolean = false) : void
        {
            var _loc_2:Boolean = false;
            if (this._position < 0)
            {
                return;
            }
            if (param1)
            {
                _loc_2 = this.autoDestroy;
                this.autoDestroy = false;
                this.stop();
                this.autoDestroy = _loc_2;
            }
            if (this._looped)
            {
                if (this._position == 0)
                {
                    if (this._channel == null)
                    {
                        this._channel = this._sound.play(0, 9999, this._transform);
                    }
                    if (this._channel == null)
                    {
                        exists = false;
                    }
                }
                else
                {
                    this._channel = this._sound.play(this._position, 0, this._transform);
                    if (this._channel == null)
                    {
                        exists = false;
                    }
                    else
                    {
                        this._channel.addEventListener(Event.SOUND_COMPLETE, this.looped);
                    }
                }
            }
            else if (this._position == 0)
            {
                if (this._channel == null)
                {
                    this._channel = this._sound.play(0, 0, this._transform);
                    if (this._channel == null)
                    {
                        exists = false;
                    }
                    else
                    {
                        this._channel.addEventListener(Event.SOUND_COMPLETE, this.stopped);
                    }
                }
            }
            else
            {
                this._channel = this._sound.play(this._position, 0, this._transform);
                if (this._channel == null)
                {
                    exists = false;
                }
            }
            active = this._channel != null;
            this._position = 0;
            return;
        }// end function

        public function resume() : void
        {
            if (this._position <= 0)
            {
                return;
            }
            if (this._looped)
            {
                this._channel = this._sound.play(this._position, 0, this._transform);
                if (this._channel == null)
                {
                    exists = false;
                }
                else
                {
                    this._channel.addEventListener(Event.SOUND_COMPLETE, this.looped);
                }
            }
            else
            {
                this._channel = this._sound.play(this._position, 0, this._transform);
                if (this._channel == null)
                {
                    exists = false;
                }
            }
            active = this._channel != null;
            return;
        }// end function

        public function pause() : void
        {
            if (this._channel == null)
            {
                this._position = -1;
                return;
            }
            this._position = this._channel.position;
            this._channel.stop();
            if (this._looped)
            {
                while (this._position >= this._sound.length)
                {
                    
                    this._position = this._position - this._sound.length;
                }
            }
            if (this._position <= 0)
            {
                this._position = 1;
            }
            this._channel = null;
            active = false;
            return;
        }// end function

        public function stop() : void
        {
            this._position = 0;
            if (this._channel != null)
            {
                this._channel.stop();
                this.stopped();
            }
            return;
        }// end function

        public function fadeOut(param1:Number, param2:Boolean = false) : void
        {
            this._pauseOnFadeOut = param2;
            this._fadeInTimer = 0;
            this._fadeOutTimer = param1;
            this._fadeOutTotal = this._fadeOutTimer;
            return;
        }// end function

        public function fadeIn(param1:Number) : void
        {
            this._fadeOutTimer = 0;
            this._fadeInTimer = param1;
            this._fadeInTotal = this._fadeInTimer;
            this.play();
            return;
        }// end function

        public function get volume() : Number
        {
            return this._volume;
        }// end function

        public function set volume(param1:Number) : void
        {
            this._volume = param1;
            if (this._volume < 0)
            {
                this._volume = 0;
            }
            else if (this._volume > 1)
            {
                this._volume = 1;
            }
            this.updateTransform();
            return;
        }// end function

        public function getActualVolume() : Number
        {
            return this._volume * this._volumeAdjust;
        }// end function

        function updateTransform() : void
        {
            this._transform.volume = (FlxG.mute ? (0) : (1)) * FlxG.volume * this._volume * this._volumeAdjust;
            if (this._channel != null)
            {
                this._channel.soundTransform = this._transform;
            }
            return;
        }// end function

        protected function looped(event:Event = null) : void
        {
            if (this._channel == null)
            {
                return;
            }
            this._channel.removeEventListener(Event.SOUND_COMPLETE, this.looped);
            this._channel = null;
            this.play();
            return;
        }// end function

        protected function stopped(event:Event = null) : void
        {
            if (!this._looped)
            {
                this._channel.removeEventListener(Event.SOUND_COMPLETE, this.stopped);
            }
            else
            {
                this._channel.removeEventListener(Event.SOUND_COMPLETE, this.looped);
            }
            this._channel = null;
            active = false;
            if (this.autoDestroy)
            {
                this.destroy();
            }
            return;
        }// end function

        protected function gotID3(event:Event = null) : void
        {
            FlxG.log("got ID3 info!");
            if (this._sound.id3.songName.length > 0)
            {
                this.name = this._sound.id3.songName;
            }
            if (this._sound.id3.artist.length > 0)
            {
                this.artist = this._sound.id3.artist;
            }
            this._sound.removeEventListener(Event.ID3, this.gotID3);
            return;
        }// end function

    }
}
